﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace WeatherNet.yahoo
{
    public sealed class YQLWeatherQuery
    {
        private const string weatherUrl = "http://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text in {0} )";

        public async Task<IEnumerable<queryChannel>> GetWeatherValues(params string[] places)
        {
            var results = new List<queryChannel>();
            if (places != null && places.Count() > 0)
            {
                string placeArg = string.Format("(\"{0}\")", string.Join("\",\"", places));
                var url = string.Format(weatherUrl, placeArg);

                try
                {
                    var client = new HttpClient();
                    var content = await client.GetStringAsync(url);
                    var queryResult = ToObject<query>(content);
                    results.AddRange(queryResult.results);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                }
            }
            return results;
        }

        private T ToObject<T>(string content)
        {
            try
            {
                var ser = new XmlSerializer(typeof(T));
                using (StringReader sr = new StringReader(content))
                {
                    var result = (T)ser.Deserialize(sr);
                    return result;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
            return default(T);
        }


        #region Auto gen

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
        public partial class query
        {
            private queryChannel[] resultsField;

            private int countField;

            private System.DateTime createdField;

            private string langField;

            /// <remarks/>
            [System.Xml.Serialization.XmlArrayItemAttribute("channel", IsNullable = false)]
            public queryChannel[] results
            {
                get
                {
                    return this.resultsField;
                }
                set
                {
                    this.resultsField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.yahooapis.com/v1/base.rng")]
            public int count
            {
                get
                {
                    return this.countField;
                }
                set
                {
                    this.countField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.yahooapis.com/v1/base.rng")]
            public System.DateTime created
            {
                get
                {
                    return this.createdField;
                }
                set
                {
                    this.createdField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.yahooapis.com/v1/base.rng")]
            public string lang
            {
                get
                {
                    return this.langField;
                }
                set
                {
                    this.langField = value;
                }
            }
        }


        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class queryChannel
        {

            private string titleField;

            private string linkField;

            private string descriptionField;

            private string languageField;

            private string lastBuildDateField;

            private int ttlField;

            private location locationField;

            private units unitsField;

            private wind windField;

            private atmosphere atmosphereField;

            private astronomy astronomyField;

            private queryChannelImage imageField;

            private queryChannelItem itemField;

            /// <remarks/>
            public string title
            {
                get
                {
                    return this.titleField;
                }
                set
                {
                    this.titleField = value;
                }
            }

            /// <remarks/>
            public string link
            {
                get
                {
                    return this.linkField;
                }
                set
                {
                    this.linkField = value;
                }
            }

            /// <remarks/>
            public string description
            {
                get
                {
                    return this.descriptionField;
                }
                set
                {
                    this.descriptionField = value;
                }
            }

            /// <remarks/>
            public string language
            {
                get
                {
                    return this.languageField;
                }
                set
                {
                    this.languageField = value;
                }
            }

            /// <remarks/>
            public string lastBuildDate
            {
                get
                {
                    return this.lastBuildDateField;
                }
                set
                {
                    this.lastBuildDateField = value;
                }
            }

            /// <remarks/>
            public int ttl
            {
                get
                {
                    return this.ttlField;
                }
                set
                {
                    this.ttlField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public location location
            {
                get
                {
                    return this.locationField;
                }
                set
                {
                    this.locationField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public units units
            {
                get
                {
                    return this.unitsField;
                }
                set
                {
                    this.unitsField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public wind wind
            {
                get
                {
                    return this.windField;
                }
                set
                {
                    this.windField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public atmosphere atmosphere
            {
                get
                {
                    return this.atmosphereField;
                }
                set
                {
                    this.atmosphereField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public astronomy astronomy
            {
                get
                {
                    return this.astronomyField;
                }
                set
                {
                    this.astronomyField = value;
                }
            }

            /// <remarks/>
            public queryChannelImage image
            {
                get
                {
                    return this.imageField;
                }
                set
                {
                    this.imageField = value;
                }
            }

            /// <remarks/>
            public queryChannelItem item
            {
                get
                {
                    return this.itemField;
                }
                set
                {
                    this.itemField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class location
        {

            private string cityField;

            private string countryField;

            private string regionField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string city
            {
                get
                {
                    return this.cityField;
                }
                set
                {
                    this.cityField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string country
            {
                get
                {
                    return this.countryField;
                }
                set
                {
                    this.countryField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string region
            {
                get
                {
                    return this.regionField;
                }
                set
                {
                    this.regionField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class units
        {

            private string distanceField;

            private string pressureField;

            private string speedField;

            private string temperatureField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string distance
            {
                get
                {
                    return this.distanceField;
                }
                set
                {
                    this.distanceField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string pressure
            {
                get
                {
                    return this.pressureField;
                }
                set
                {
                    this.pressureField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string speed
            {
                get
                {
                    return this.speedField;
                }
                set
                {
                    this.speedField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string temperature
            {
                get
                {
                    return this.temperatureField;
                }
                set
                {
                    this.temperatureField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class wind
        {

            private int chillField;

            private int directionField;

            private int speedField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int chill
            {
                get
                {
                    return this.chillField;
                }
                set
                {
                    this.chillField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int direction
            {
                get
                {
                    return this.directionField;
                }
                set
                {
                    this.directionField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int speed
            {
                get
                {
                    return this.speedField;
                }
                set
                {
                    this.speedField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class atmosphere
        {

            private int humidityField;

            private decimal pressureField;

            private int risingField;

            private decimal visibilityField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int humidity
            {
                get
                {
                    return this.humidityField;
                }
                set
                {
                    this.humidityField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public decimal pressure
            {
                get
                {
                    return this.pressureField;
                }
                set
                {
                    this.pressureField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int rising
            {
                get
                {
                    return this.risingField;
                }
                set
                {
                    this.risingField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public decimal visibility
            {
                get
                {
                    return this.visibilityField;
                }
                set
                {
                    this.visibilityField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class astronomy
        {

            private string sunriseField;

            private string sunsetField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string sunrise
            {
                get
                {
                    return this.sunriseField;
                }
                set
                {
                    this.sunriseField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string sunset
            {
                get
                {
                    return this.sunsetField;
                }
                set
                {
                    this.sunsetField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class queryChannelImage
        {

            private string titleField;

            private int widthField;

            private int heightField;

            private string linkField;

            private string urlField;

            /// <remarks/>
            public string title
            {
                get
                {
                    return this.titleField;
                }
                set
                {
                    this.titleField = value;
                }
            }

            /// <remarks/>
            public int width
            {
                get
                {
                    return this.widthField;
                }
                set
                {
                    this.widthField = value;
                }
            }

            /// <remarks/>
            public int height
            {
                get
                {
                    return this.heightField;
                }
                set
                {
                    this.heightField = value;
                }
            }

            /// <remarks/>
            public string link
            {
                get
                {
                    return this.linkField;
                }
                set
                {
                    this.linkField = value;
                }
            }

            /// <remarks/>
            public string url
            {
                get
                {
                    return this.urlField;
                }
                set
                {
                    this.urlField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class queryChannelItem
        {

            private string titleField;

            private decimal latField;

            private decimal longField;

            private string linkField;

            private string pubDateField;

            private condition conditionField;

            private string descriptionField;

            private forecast[] forecastField;

            private queryChannelItemGuid guidField;

            /// <remarks/>
            public string title
            {
                get
                {
                    return this.titleField;
                }
                set
                {
                    this.titleField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2003/01/geo/wgs84_pos#")]
            public decimal lat
            {
                get
                {
                    return this.latField;
                }
                set
                {
                    this.latField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://www.w3.org/2003/01/geo/wgs84_pos#")]
            public decimal @long
            {
                get
                {
                    return this.longField;
                }
                set
                {
                    this.longField = value;
                }
            }

            /// <remarks/>
            public string link
            {
                get
                {
                    return this.linkField;
                }
                set
                {
                    this.linkField = value;
                }
            }

            /// <remarks/>
            public string pubDate
            {
                get
                {
                    return this.pubDateField;
                }
                set
                {
                    this.pubDateField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public condition condition
            {
                get
                {
                    return this.conditionField;
                }
                set
                {
                    this.conditionField = value;
                }
            }

            /// <remarks/>
            public string description
            {
                get
                {
                    return this.descriptionField;
                }
                set
                {
                    this.descriptionField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("forecast", Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
            public forecast[] forecast
            {
                get
                {
                    return this.forecastField;
                }
                set
                {
                    this.forecastField = value;
                }
            }

            /// <remarks/>
            public queryChannelItemGuid guid
            {
                get
                {
                    return this.guidField;
                }
                set
                {
                    this.guidField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class condition
        {

            private int codeField;

            private string dateField;

            private int tempField;

            private string textField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int code
            {
                get
                {
                    return this.codeField;
                }
                set
                {
                    this.codeField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string date
            {
                get
                {
                    return this.dateField;
                }
                set
                {
                    this.dateField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int temp
            {
                get
                {
                    return this.tempField;
                }
                set
                {
                    this.tempField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string text
            {
                get
                {
                    return this.textField;
                }
                set
                {
                    this.textField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0", IsNullable = false)]
        public partial class forecast
        {

            private int codeField;

            private string dateField;

            private string dayField;

            private int highField;

            private int lowField;

            private string textField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int code
            {
                get
                {
                    return this.codeField;
                }
                set
                {
                    this.codeField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string date
            {
                get
                {
                    return this.dateField;
                }
                set
                {
                    this.dateField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string day
            {
                get
                {
                    return this.dayField;
                }
                set
                {
                    this.dayField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int high
            {
                get
                {
                    return this.highField;
                }
                set
                {
                    this.highField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public int low
            {
                get
                {
                    return this.lowField;
                }
                set
                {
                    this.lowField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string text
            {
                get
                {
                    return this.textField;
                }
                set
                {
                    this.textField = value;
                }
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class queryChannelItemGuid
        {

            private bool isPermaLinkField;

            private string valueField;

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public bool isPermaLink
            {
                get
                {
                    return this.isPermaLinkField;
                }
                set
                {
                    this.isPermaLinkField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlTextAttribute()]
            public string Value
            {
                get
                {
                    return this.valueField;
                }
                set
                {
                    this.valueField = value;
                }
            }
        }

        #endregion Auto gen

    }
}
